"""
This module implements the utils for computing Feynman diagram expansion.
"""


# TODO: finish this.


struct Node
    index
end


struct Vertex
    a::Node  # node index on one side;
    b::Node  # node index on the other side.
end


struct Graph
    vertices::Vector{Vertex}
end


struct Tensor
    graph::Graph
end


function basegraph(indices, symmetricindices...)::Graph
    # Collect nodes
    nodes = Node[]
    for i in indices
        is_symmetric = false
        for S in symmetricindices
            if i in S
                push!(nodes, Node(S[1]))
                is_symmetric = true
                break
            end
        end
        if !is_symmetric
            push!(nodes, Node(i))
        end
    end

    # Formulate base graph
    if length(nodes) == 1
        # self-circle
        Graph([Vertex(nodes[1], nodes[1])])

    elseif length(nodes) == 2
        # line
        Graph([Vertex(nodes[1], nodes[2])])

    else
        # multi-node cycle
        vertices = Vertex[]
        for i = 1:length(nodes)
            if i == length(nodes)
                push!(vertices, Vertex(nodes[i], nodes[1]))
            else
                push!(vertices, Vertex(nodes[i], nodes[i+1]))
            end
        end
        Graph(vertices)
    end
end


function basetensor(indices, symmetricindices...)::Tensor
    graph = basegraph(indices, symmetricindiecs...)
end



# TODO
function contract(x::Graph, indices::Vector{Node})::Graph
end


function Base.:*(x::Graph, y::Graph)::Graph
    contract(x, y)
end


function Base.:*(x::Tensor, y::Tensor)::Tensor
    Tensor(x.graph * y.graph)
end

xx = basegraph(1:4, [1, 2], [3, 4])
